package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl;

import com.alibaba.fastjson.JSON;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.TaskLinkStatusEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.TaskNodeTypeEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.application.event.EventResponse;
import com.iwhalecloud.citybrain.flow.platform.manager.application.event.NodeEventExecuter;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.ParseRenderedVariable;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.exception.EventCallException;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.eventconfig.DeployedEventConfigDomain;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.common.api.delegate.event.FlowableEngineEventType;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * @author: liyang
 * @date: 2021/11/22 14:22
 */
@Slf4j
@Service
@Order(1)
public class MultiExecutionCompletedEventCallProcessor implements MultiExecutionCompletedProcessor {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private CommonTaskEventProcessor commonTaskEventProcessor;

    @Autowired
    private NodeEventExecuter nodeEventExecuter;

    @Autowired
    private TaskService taskService;

    @Autowired
    private MultiExecutionCompletedSyncDataProcessor syncDataProcessor;

    @Override
    public void process(ExecutionEntity execution) throws Exception {
        String activityId = execution.getActivityId();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(execution.getProcessInstanceId()).singleResult();
        List<DeployedEventConfigDomain> eventConfigs = commonTaskEventProcessor.resolveEventConfigList(
                processInstance.getProcessInstanceId(),activityId, FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION.name());
        if (CollectionUtils.isNotEmpty(eventConfigs)){
            for (DeployedEventConfigDomain eventConfig : eventConfigs) {
                String url = eventConfig.getCallbackContent();
                // 获取流程处理的任务列表,获取处理人
                List<Task> taskList = taskService.createTaskQuery().processInstanceId(execution.getProcessInstanceId()).list();
                if (CollectionUtils.isNotEmpty(taskList)) {
                    for (Task taskObj : taskList) {
                        if(StringUtils.isNotBlank(taskObj.getAssignee())) {
                            execution.setTransientVariable("assignee",taskObj.getAssignee());
                            break;
                        }
                    }
                }
                // 根据变量参数解析请求的url
                url = ParseRenderedVariable.parseRenderedVariable(url,execution);
                String requestBody = eventConfig.getRequestBody();
                if (StringUtils.isNotBlank(requestBody)){
                    requestBody = ParseRenderedVariable.parseRenderedVariable(requestBody,execution);
                }
                if (Objects.equals("sync",eventConfig.getCallMethod())){
                    try {
                        EventResponse eventResponse = nodeEventExecuter.syncCall(url,requestBody);
                        log.info("eventResponse:"+ JSON.toJSONString(eventResponse));
                    } catch (EventCallException eventCallException) {
                        log.error("execute multiTask eventCall error", eventCallException);
                        // 回滚待办任务状态
                        this.rollbackTask(execution, TaskLinkStatusEnum.TODO.getCode(), TaskNodeTypeEnum.QQRW.getCode());
                        throw eventCallException;
                    }
                }else{
                    try {
                        nodeEventExecuter.asyncCall(url,requestBody);
                        log.info("execute multiTask eventCall success");
                    } catch (EventCallException eventCallException) {
                        log.error("execute multiTask eventCall error", eventCallException);
                    }
                }
            }
        }
    }

    /**
     * 回滚待办任务
     *
     * @param executionEntity
     * @param taskLinkStatus
     * @param taskNodeType
     * @throws Exception
     */
    @Override
    public void rollbackTask(ExecutionEntity executionEntity, String taskLinkStatus, String taskNodeType) throws Exception {
        syncDataProcessor.rollbackTask(executionEntity, taskLinkStatus, taskNodeType);
    }
}